/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package fr.sonictools.xml;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;

/**
 * 
 * @author jbenech
 */
public class JaxbXmlParser<T> {
	public static final String ENCODING_UTF8 = "UTF-8";
	public static final String ENCODING_ISO8859 = "ISO-8859-1";
	private Unmarshaller m_unmarshaller = null;
	private Marshaller m_marshaller = null;
	private String m_encoding = ENCODING_UTF8;
	
	/**
	 * 
	 * Parser in charge to marshall/unmarshall objects
	 * 
	 * @param jc
	 *            jaxb context
	 * @param encoding
	 *            if null, UTF-8 is used
	 * @throws javax.xml.bind.JAXBException
	 */
	public JaxbXmlParser(JAXBContext jc, String encoding) throws JAXBException {
		m_encoding = encoding == null ? ENCODING_UTF8 : encoding;
		m_unmarshaller = jc.createUnmarshaller();
		m_marshaller = jc.createMarshaller();
		m_marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
		m_marshaller.setProperty(Marshaller.JAXB_ENCODING, m_encoding);// UTF-8/ISO-8859-1
	}

	/**
	 * Parser in charge to marshall/unmarshall objects
	 * 
	 * @deprecated please, no more use this constructor.
	 * 
	 * @param business_package
	 *            This is the package containing the ObjectFactory class
	 * @throws javax.xml.bind.JAXBException
	 */
	public JaxbXmlParser(String business_package) throws JAXBException {
		this(JAXBContext.newInstance(business_package), ENCODING_UTF8);
	}

	/**
	 * @param RootObjClazz
	 *            class of the object representing the root xml tag
	 * @throws javax.xml.bind.JAXBException
	 */
	public JaxbXmlParser(Class<T> RootObjClazz, String encoding)
			throws JAXBException {
		this(JAXBContext.newInstance(RootObjClazz), encoding);

	}

	/**
	 * Load object from the XML file
	 * 
	 * @param path
	 * @return
	 * @throws javax.xml.bind.JAXBException
	 */
	public T loadObject(String path) throws JAXBException {
		return (T) m_unmarshaller.unmarshal(new File(path));
	}

	/**
	 * 
	 * Load objects from the XMl file using stax parser
	 * 
	 * @param path
	 * @return
	 * @throws javax.xml.bind.JAXBException
	 * @throws javax.xml.stream.XMLStreamException
	 * @throws java.io.FileNotFoundException
	 */
	public T loadObjectUsingStax(String path) throws JAXBException,
			XMLStreamException, FileNotFoundException {
		XMLEventReader xmlEventReader = null;
		xmlEventReader = XMLInputFactory.newInstance().createXMLEventReader(
				new FileInputStream(path), "UTF-8");

		return (T) (xmlEventReader == null ? null : m_unmarshaller
				.unmarshal(xmlEventReader));
	}

	/**
	 * 
	 * Store object as XML file
	 * 
	 * @param objectToStore
	 * @param path
	 * @throws java.io.FileNotFoundException
	 * @throws javax.xml.bind.JAXBException
	 */
	public void storeObjectUsingStax(T objectToStore, String path)
			throws FileNotFoundException, JAXBException {
		OutputStream os = new FileOutputStream(path);
		m_marshaller.marshal(objectToStore, os);
	}

}
